import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 徐海涛
 * Date: 2022-01-06
 * Time: 15:36
 * LIst的使用
 */
class MyArrayList1<E> {
    private Object[] elementData;//数组
    private int usedSize;//代表有效的数据个数
    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//空数组

    public MyArrayList1() {//不给容量
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }
    public MyArrayList1(int capacity) {//给容量为capacity
        //对参数进行判断
        if(capacity > 0) {
            this.elementData = new Object[capacity];//数组容量为capacity
        }else if(capacity == 0) {
            this.elementData = new Object[0];
        }else {
            throw new IllegalArgumentException("初始化的容量不能为负数");
        }

    }


    public boolean add(E e) {//相当于存放在了数组的最后位置
        //确定一个真正的容量，预测->扩容[把检查顺序表空和满和扩容放到了一起]
        ensureCapacityInternal(usedSize+1);
        elementData[usedSize] = e;
        usedSize++;
        return true;
    }
    private void ensureCapacityInternal(int minCapacity){
        //1.计算出 需要的容量
        int capacity = calculateCapacity(elementData,minCapacity);
        //2.拿着计算出的容量，去看满了扩容。空的也是
        ensureCapacityInternal(capacity);

    }
    private void ensureExplicitCapacity(int minCapacity) {
        //进不去if语句，数组还没放满
        if (minCapacity - elementData.length > 0)
            //扩容了
            grow(minCapacity);
    }
    private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE-8;
    private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + (oldCapacity >> 1);//1.5倍扩容
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity -  MAX_ARRAY_SIZE> 0)
            newCapacity = hugeCapacity(minCapacity);
        // minCapacity is usually close to size, so this is a win:
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

    private static int hugeCapacity(int minCapacity) {
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        return (minCapacity > MAX_ARRAY_SIZE) ?
                Integer.MAX_VALUE :
                MAX_ARRAY_SIZE;
    }

    private static int calculateCapacity(Object[] elementData, int minCapacity){
        //1.是否之前elementData数组分配过大小
        if(elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            return Math.max(10,minCapacity);
        }
        //2.分配过 就返回+1 后的值
        return minCapacity;
    }
    /* index位置添加元素

     */


    public void add(int index,E e) {
        rangeCheckForAdd(index);
        ensureCapacityInternal(usedSize+1);

        copy(index,e);

        usedSize++;
    }


    private void copy(int index,E e) {
        for (int i = usedSize-1; i >= index ; i--) {
            elementData[i+1] = elementData[i];//i的值给i+1

        }
        elementData[index] = e;
    }







    private void rangeCheckForAdd(int index) {
        if(index < 0 || index > size()) {
            throw new IndexOutOfBoundsException("index位置不合法，不能插入！");
        }

    }

    /**
     * 获取顺序表的大小
     * @return
     */
    public int size() {
        return this.usedSize;
    }


}




public class TestDemo3 {
    public static void main9(String[] args) {
        MyArrayList1<String> list1 = new MyArrayList1<>();
        list1.add("av");
        list1.add("cc");
        list1.add("ssss");
        list1.add("sdad");
        list1.add(0,"gaobo");
        System.out.println("sadsadsad");

    }







    public static void main8(String[] args) {
        //结论

        ArrayList<String> list2 = new ArrayList<>();
        //初始的大小是几？是0
        list2.add("hello");//当第一次存放数据元素的时候，顺序表分配大小是10
        //超出以后以1.5倍进行扩容
        ArrayList<String> list3 = new ArrayList<>(13);
        //初始大小是指定的13


    }

    public static void main7(String[] args) {
        ArrayList<String> list2 = new ArrayList<>();
        list2.add("a");
        list2.add("b");
        list2.add("c");
        list2.add("c");
        list2.add("f");
        list2.add("d");
        //截取下标1和下标3
        List<String> sub = list2.subList(1,3);
        System.out.println(sub);
        System.out.println(list2);
        System.out.println("============================");
        sub.set(0,"p");
        System.out.println(sub);
    }

    public static void main6(String[] args) {
        ArrayList<String> list2 = new ArrayList<>();
        list2.add("a");
        list2.add("b");
        list2.add("c");

        //删除某个下标的元素
        //先判断是否包含，包含了以后在进行删除
       /* boolean ret = list2.remove("a");
        System.out.println(ret);
        System.out.println(list2);
        //得到下标元素
        String ret2 = list2.get(2);
        System.out.println(ret2);
        System.out.println(list2);**/
        //更新下下标元素
       /* String ret3 = list2.set(2,"gaobo");
        System.out.println("原来的字符串"+ret3);
        System.out.println(list2);**/
        //清空
        /*list2.clear();
        System.out.println(list2);**/
        //包含
        System.out.println(list2);
        System.out.println(list2.contains("b"));
        //找下标
        System.out.println(list2.indexOf("c"));
        //找到最后一个下标
        System.out.println(list2.lastIndexOf("c"));




    }



    public static void main5(String[] args) {
        ArrayList<String> list2 = new ArrayList<>();
        list2.add("a");//add方法默认是放到数组最后一个位置的
        list2.add("b");
        list2.add("c");
        System.out.println(list2);
        list2.add(0,"xht");
        System.out.println(list2);

        ArrayList<String> list3 = new ArrayList<>();
        list3.add("我是测试List1");
        list3.add("我是测试List2");
        list3.add("我是测试List3");
        list2.addAll(list3);
        System.out.println(list2);

    }








    public static void main4(String[] args) {
        ArrayList<String> list2 = new ArrayList<>();
        list2.add("hello");
        list2.add("bit");
        list2.add("hhh");
        ListIterator<String> it2 = list2.listIterator();
        while (it2.hasNext()) {
            String str = it2.next();
            if(str.equals("hello")){
                it2.add("xxx");//默认在hello后面添加
            }else {
                System.out.print(str + " ");
            }
        }
        System.out.println("================");
        System.out.println(list2);
    }








    public static void main3(String[] args) {
        ArrayList<String> list2 = new ArrayList<>();
        list2.add("hello");
        list2.add("bit");
        list2.add("hhh");
        Iterator<String> it = list2.iterator();
        while (it.hasNext()) {
            String ret = it.next();//先将所有元素遍历.0

            if(ret.equals("hello")) {
                it.remove();//首先需要使用next方法迭代出集合的元素，然后才能使用move方法
            }else {
                System.out.print(ret + " ");
            }
        }


        System.out.println();
        System.out.println("======迭代器List相关打印==============");
        ListIterator<String> it2 = list2.listIterator();
        while (it2.hasNext()) {
            String ret2 = it2.next();
            if(ret2.equals("hello")) {
                it2.remove();
            }else {
                System.out.print(ret2+ " ");
            }
        }
    }







    public static void main2(String[] args) {
        ArrayList<String> list2 = new ArrayList<>();
        list2.add("hello");
        list2.add("bit");
        list2.add("hhh");
        System.out.print(list2);//以字符串形式输出，底层默认toString方法
        System.out.println();
        System.out.println("=======第一种打印方式===========");
        for (int i = 0; i < list2.size(); i++) {//取出来
            System.out.print(list2.get(i)+ " ");
        }
        System.out.println();
        System.out.println("=========第二种打印方式=========");
        for (String s:list2){//foreach循环冒号左面为 参数类型 右边为 打印的元素
            System.out.print(s+ " ");
        }
        System.out.println();
        System.out.println("======迭代器打印==============");
        Iterator<String> it = list2.iterator();
        while (it.hasNext()) {
            System.out.println(it.next()+ " ");
        }

        System.out.println();
        System.out.println("======迭代器List相关打印==============");
        ListIterator<String> it2 = list2.listIterator();
        while (it2.hasNext()) {
            System.out.print(it2.next()+ " ");
        }

    }



    public static void main1(String[] args) {
        List<String> list = new ArrayList<>(20);//List接口

        ArrayList<String> list2 = new ArrayList<>();
        list2.add("hello");
        list2.add("bit");
        list2.add("hhh");
        System.out.println(list2);//以字符串形式输出，底层默认toString方法

        //使用另外一个ArrayList对List3进行初始化
        ArrayList<String> list3 = new ArrayList<>(list2);

    }

}
